The message system provides a way to notify about events and exchange information. At the core of the message system is KzuMessageDispatcher
. The dispatcher acts as a mediator between message senders and handlers. It maintains the list of active message handlers and the message queue. You can access the message dispatcher from any object with kzuObjectNodeGetMessageDispatcher()
.
Every message is represented by a KzuMessage
object created by kzuMessageDispatcherCreateMessage()
. Messages type describes the nature of event or information (for example, Click and ItemSelected), and arguments to describe the data associated within the message (for example, TouchCoordinates and ItemNumber). The type of a message is described with KzuMessageType
objects.
Message arguments are described and accessed like properties with KzuPropertyType
objects. kzuMessageSet*Argument()
functions set and kzuMessageGet*ArgumentDefault()
functions retrieve arguments with the underlying storage type for arguments Float, Bool, Vector3, and so on. If the message does not have the argument the kzuMessageGet*ArgumentDefault()
functions return the default value registered in the property type. Kanzi provides the built-in message types in kzu_general_messages.h
.
Because the dispatcher manages the lifetime of the message object and associated arguments, do not keep the references to those objects.
The message system has inbuilt support for timer messages. kzuMessageDispatcherAddTimerHandler()
subscribes and kzuMessageDispatcherRemoveTimerHandler()
unsubscribes a timer message. During subscription set the interval for the timer and the timer behavior:
There are two ways you can dispatch a message to the handlers, each dispatch methods has its advantages and disadvantages:
kzuMessageDispatcherDispatchMessage()
places the message into the message queue and returns immediately. The handlers are notified later, usually at the next frame.kzuMessageDispatcherDispatchMessage()
method defers message handling and allows processing of one message at a time. Take into account that the message is delivered at an unspecified time.kzuMessageDispatcherDispatchMessageSynchronous()
notifies the handlers immediately before the function call returns. kzuMessageDispatcherDispatchMessageSynchronous()
method provides the opportunity for the handlers to react to the message immediately. The drawback of this method is nested message handling where a handler could initiate another message dispatch using Send. This can complicate the logic in the handlers since they need to take care of reentrancy and object lifetime management.Use kzuMessageDispatcherDispatchMessage()
and change to kzuMessageDispatcherDispatchMessageSynchronous()
only if it improve application responsiveness or simplify logic.
All messages in Kanzi are routed messages. When a message is dispatched the system walks though the scene graph from the root node to the target of the message in a process called tunnelling and then walks back in a process called bubbling. At each scene graph node passed the system looks for handlers for the dispatched message. This means that handlers can be installed at any place in the graph effectively intercepting messages before they reach their destination or gathering messages from many sources.
Bubbling is the phase where most of the messages should be handled, whereas Tunnelling is usually used for intercepting or filtering messages.
Receivers are implemented as functions and passed as pointers to kzuMessageDispatcherAddHandler()
, kzuMessageDispatcherAddTunnellingHandler()
. To provide context to the receiver implementation, provide a pointer to the user data at registration time. Use kzuMessageDispatcherRemoveHandler()
to remove handlers.
To create a custom message in Kanzi Studio:
In the Library right-click Property Types and select Property Type.